/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package co.edu.udistrital.erpgrid.utilidades.ftp;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ResourceBundle;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Utilitario para conexiónes ftp.
 *
 * @author rcabezas
 */
public class FtpUtil {

    /** Logger. */
    private final static transient Logger LOG = LoggerFactory.getLogger(FtpUtil.class);
    
    /** The instance. */
    private static FtpUtil instance;
    
    /** The RS. */
    private static transient ResourceBundle RS = ResourceBundle
	 .getBundle("utilidadesConf");
    
    /**
	 * Datos del ftp.
	 * @uml.property  name="_SERVER"
	 */
    private transient String _SERVER;
    
    /**
	 * The _ username.
	 * @uml.property  name="_USERNAME"
	 */
    private transient String _USERNAME;
    
    /**
	 * The _ password.
	 * @uml.property  name="_PASSWORD"
	 */
    private transient String _PASSWORD;
    
    /**
	 * The _ home.
	 * @uml.property  name="_HOME"
	 */
    private transient String _HOME;
    
    /**
	 * Objeto ftp.
	 * @uml.property  name="ftp"
	 * @uml.associationEnd  
	 */
    private transient FTPClient ftp;

    /**
     * Instantiates a new ftp util.
     *
     * @param server the server
     */
    public FtpUtil(String server) {
        _SERVER = server;
        _USERNAME = RS.getString("ftp.username");
        _PASSWORD = RS.getString("ftp.password");
        _HOME = RS.getString("ftp.home");

    }

    /**
     * Listar archivos del FTP.
     *
     * @param folder carpeta a listar del ftp
     * @return lista de archivos
     */
    public FTPFile[] listarArchivos(String folder) {
        FTPFile[] files = null;
        try {
            conectarFTP();
            LOG.debug(ftp.getReplyString());

            if (folder != null && !folder.isEmpty()) {
                ftp.changeWorkingDirectory(folder);
            }
            files = ftp.listFiles();

        } catch (IOException e) {
            LOG.error(e.getMessage(), e);
//            String mensaje = MensajesUtil.getInstance().formatMessage("ftp.excepcion.lista", e.getMessage());
//            throw new SistemaException(mensaje, e);
        } finally {
            desconectarFTP();
        }
        return files;
    }

    /**
     * Obtener bytes de un archivo del FTP.
     *
     * @param nombreArchivo the nombre archivo
     * @return bytes del archivo del FTP
     */
    public byte[] obtenerArchivoFtp(String nombreArchivo) {
    	LOG.info("SERVIDOR: "+this._SERVER);
    	LOG.info("Archivo: "+nombreArchivo);
        byte[] archivo = null;
        ByteArrayOutputStream baos = null;
        try {
            conectarFTP();
            
            baos = new ByteArrayOutputStream();
            ftp.retrieveFile(nombreArchivo, baos);
            archivo = baos.toByteArray();
        } catch (IOException e) {
            LOG.error(e.getMessage(), e);
//            String mensaje = MensajesUtil.getInstance().formatMessage("ftp.excepcion.archivo", e.getMessage());
//            throw new SistemaException(mensaje, e);
        } finally {
            if (baos != null) {
                try {
                    baos.close();
                } catch (IOException ex) {
                    LOG.error(ex.getMessage(), ex);
                }
            }
            desconectarFTP();
        }
        return archivo;
    }
    
    /**
     * Cargar archivo del inputStream en el folder y con el nombre especificado en el objeto de transferencia.
     *
     * @param ftpTO objeto con datos a cargar
     */
    public void cargarArchivoFtp(FtpTO ftpTO) {
        try {
            conectarFTP();
            ftp.changeWorkingDirectory(ftpTO.getFolder());
            boolean ok = ftp.storeFile(ftpTO.getNombreArchivo(), ftpTO.getInputStream());
            if(!ok){
//                String mensaje = MensajesUtil.getInstance().formatMessage("ftp.excepcion.carga"+ftp.getReplyCode());
//                throw new LogicaException(mensaje);
            }
        } catch (IOException e) {
            LOG.error(e.getMessage(), e);
//            String mensaje = MensajesUtil.getInstance().formatMessage("ftp.excepcion.carga", e.getMessage());
//            throw new SistemaException(mensaje, e);
        }finally{
            desconectarFTP();
        }
    }
    
    /**
     * Cargar directorio en el folder y con el nombre especificado en el objeto de transferencia.
     *
     * @param ftpTO objeto con datos a crear
     */
    public void crearDirectorioFtp(FtpTO ftpTO) {
        try {
            conectarFTP();
            ftp.changeWorkingDirectory(ftpTO.getFolder());
            int ok = ftp.mkd(ftpTO.getNombreArchivo());
            if(ok!=257){
//                String mensaje = MensajesUtil.getInstance().formatMessage("ftp.excepcion.directorio"+ftp.getReplyCode());
//                throw new LogicaException(mensaje);
            }
        } catch (IOException e) {
            LOG.error(e.getMessage(), e);
//            String mensaje = MensajesUtil.getInstance().formatMessage("ftp.excepcion.directorio", e.getMessage());
//            throw new SistemaException(mensaje, e);
        }finally{
            desconectarFTP();
        }
    }
    
    /**
     * Eliminar archivo en el folder y con el nombre especificado en el objeto de transferencia.
     *
     * @param ftpTO the ftp to
     */
    public void eliminarArchivoFtp(FtpTO ftpTO) {
        try {
            conectarFTP();
            ftp.changeWorkingDirectory(ftpTO.getFolder());
            
            boolean ok = ftp.deleteFile(ftpTO.getFile().getName());
            if(!ok){
//                String mensaje = MensajesUtil.getInstance().formatMessage("ftp.excepcion.eliminar"+ftp.getReplyCode());
//                throw new LogicaException(mensaje);
            }
            
            
        } catch (IOException e) {
            LOG.error(e.getMessage(), e);
//            String mensaje = MensajesUtil.getInstance().formatMessage("ftp.excepcion.eliminar", e.getMessage());
//            throw new SistemaException(mensaje, e);
        }finally{
            desconectarFTP();
        }
    }

    /**
     * Desconectar el FTP.
     */
    private void desconectarFTP() {
        if (ftp != null) {
            try {
                // Logout from the FTP Server and disconnect
                ftp.logout();
                ftp.disconnect();
            } catch (IOException ex) {
                LOG.error(ex.getMessage(), ex);
            }
        }
    }

    /**
     * Conectar el FTP.
     *
     * @throws IOException Signals that an I/O exception has occurred.
     */
    private void conectarFTP() throws IOException {
        ftp = new FTPClient();
        // Connect and logon to FTP Server
        ftp.connect(_SERVER);
        ftp.login(_USERNAME, _PASSWORD);
        LOG.debug("Conectado a: " + _SERVER + ".");
        // List the files in the directory
        ftp.changeWorkingDirectory(_HOME);
    }
}
